package com.halfsword.creativecraft.item.custom;

import net.minecraft.network.chat.Component;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.effect.MobEffects;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ArmorItem;
import net.minecraft.world.item.ArmorMaterial;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.TooltipFlag;
import net.minecraft.world.level.Level;
import org.jetbrains.annotations.Nullable;

import java.util.*;

/**
 * 自定义盔甲物品类，支持多套盔甲效果
 *REFORGED BY DEEPSEEK
 * 由Deepseek提供项目重构
 * <h2>设计特点：</h2>
 * <ul>
 *   <li>使用 onInventoryTick 实现效果刷新机制</li>
 *   <li>添加短持续时间+刷新机制，解决效果移除问题</li>
 *   <li>优化全套盔甲检查逻辑，提高性能</li>
 *   <li>增强提示信息，显示更详细的效果说明</li>
 * </ul>
 *
 * <h3>效果机制说明：</h3>
 * <ul>
 *   <li>效果持续时间设为600,000刻（约8小时），模拟永久效果</li>
 *   <li>但每5秒（100刻）刷新一次持续时间</li>
 *   <li>确保脱下盔甲后效果自然过期消失</li>
 *   <li>避免手动移除效果的复杂逻辑</li>
 * </ul>
 */
public class ArmorItems extends ArmorItem {

    // ============================== 静态注册表 ============================== //

    /**
     * 盔甲材质 -> 效果集合 映射表
     * 存储不同材质盔甲的全套效果
     */
    private static final Map<ArmorMaterial, Set<MobEffectInstance>> MATERIAL_TO_EFFECTS_MAP = new HashMap<>();

    /**
     * 盔甲材质 -> 提示文本键 映射表
     * 用于在物品提示中显示套装效果描述
     */
    private static final Map<ArmorMaterial, String> MATERIAL_TO_TOOLTIP_MAP = new HashMap<>();

    // 静态初始化块 - 注册预设盔甲套装
    static {
        // 注册空间盔甲效果（长持续时间+高等级）
        registerArmorSet(
                ArmorMaterials.SPACE,
                Set.of(
                        new MobEffectInstance(MobEffects.DAMAGE_BOOST, 200, 15, false, false, true),
                        new MobEffectInstance(MobEffects.DAMAGE_RESISTANCE, 200, 2, false, false, true)
                ),
                "tooltip.creativecraft.space_set_bonus"
        );

        // 注册末影盔甲效果
        registerArmorSet(
                ArmorMaterials.ENDER,
                Set.of(
                        new MobEffectInstance(MobEffects.DAMAGE_RESISTANCE, 200, 0, false, false, true),
                        new MobEffectInstance(MobEffects.NIGHT_VISION, 200, 0, false, false, true)
                ),
                "tooltip.creativecraft.ender_set_bonus"
        );
    }

    // ============================== 注册API ============================== //

    /**
     * 注册一套盔甲的效果
     *
     * @param material   盔甲材质
     * @param effects    效果集合
     * @param tooltipKey 提示文本的翻译键
     */
    public static void registerArmorSet(ArmorMaterial material, Set<MobEffectInstance> effects, String tooltipKey) {
        MATERIAL_TO_EFFECTS_MAP.put(material, effects);
        MATERIAL_TO_TOOLTIP_MAP.put(material, tooltipKey);
    }

    /**
     * 获取指定材质的盔甲效果
     *
     * @param material 盔甲材质
     * @return 效果集合（可能为空，但不会为null）
     */
    public static Set<MobEffectInstance> getEffectsForMaterial(ArmorMaterial material) {
        return MATERIAL_TO_EFFECTS_MAP.getOrDefault(material, Collections.emptySet());
    }

    /**
     * 获取指定材质的提示文本键
     *
     * @param material 盔甲材质
     * @return 提示文本的翻译键
     */
    public static String getTooltipKeyForMaterial(ArmorMaterial material) {
        return MATERIAL_TO_TOOLTIP_MAP.getOrDefault(material, "tooltip.creativecraft.default_set_bonus");
    }

    // ============================== 实例方法 ============================== //

    /**
     * 构造函数
     *
     * @param material   盔甲材质
     * @param type       盔甲类型（头盔/胸甲/护腿/靴子）
     * @param properties 物品属性
     */
    public ArmorItems(ArmorMaterial material, Type type, Properties properties) {
        super(material, type, properties);
    }

    // 上次效果刷新时间（按玩家存储）
    private static final Map<UUID, Long> lastRefreshTime = new HashMap<>();

    /**
     * 物品栏更新时的处理逻辑
     *
     * <h3>工作流程：</h3>
     * <ol>
     *   <li>仅服务端执行</li>
     *   <li>每100刻（5秒）检查一次</li>
     *   <li>验证玩家是否穿戴全套盔甲</li>
     *   <li>应用符合条件的盔甲效果</li>
     * </ol>
     */
    @Override
    public void onInventoryTick(ItemStack stack, Level level, Player player, int slotIndex, int selectedIndex) {
        super.onInventoryTick(stack, level, player, slotIndex, selectedIndex);

        // 仅在服务端执行
        if (level.isClientSide()) {
            return;
        }

        // 获取当前游戏时间（刻）
        long currentTime = level.getGameTime();
        UUID playerId = player.getUUID();

        // 检查是否达到刷新间隔（100刻 = 5秒）
        if (currentTime - lastRefreshTime.getOrDefault(playerId, 0L) < 100) {
            return;
        }

        // 更新最后刷新时间
        lastRefreshTime.put(playerId, currentTime);

        // 检查是否穿戴全套盔甲
        if (hasFullSuitOfArmorOn(player)) {
            // 评估并应用所有可能的盔甲效果
            evaluateAllArmorEffects(player);
        }
    }

    /**
     * 评估并应用所有注册的盔甲效果
     *
     * @param player 要检查的玩家
     */
    private void evaluateAllArmorEffects(Player player) {
        // 遍历所有已注册的材质
        for (ArmorMaterial material : MATERIAL_TO_EFFECTS_MAP.keySet()) {
            // 检查玩家是否穿戴该材质的全套盔甲
            if (hasCorrectArmorOn(material, player)) {
                // 应用该套盔甲的所有效果
                applyArmorSetEffects(player, material);
            }
        }
    }

    /**
     * 应用一套盔甲的所有效果
     *
     * <p>效果处理逻辑：</p>
     * <ul>
     *   <li>如果玩家没有该效果，添加新效果</li>
     *   <li>如果玩家已有该效果，刷新持续时间</li>
     *
     * </ul>
     *
     * @param player   目标玩家
     * @param material 盔甲材质
     */
    private void applyArmorSetEffects(Player player, ArmorMaterial material) {
        Set<MobEffectInstance> effects = getEffectsForMaterial(material);

        for (MobEffectInstance effect : effects) {
            // 创建新的效果实例（保留原始持续时间）
            MobEffectInstance newEffect = new MobEffectInstance(
                    effect.getEffect(),
                    effect.getDuration(),  // 保持600,000刻的长持续时间
                    effect.getAmplifier(),
                    effect.isAmbient(),
                    effect.isVisible(),
                    effect.showIcon()
            );

            // 检查玩家是否已有该效果
            if (player.hasEffect(effect.getEffect())) {
                // 刷新已有效果的持续时间
                player.getEffect(effect.getEffect()).update(newEffect);
            } else {
                // 添加新效果
                player.addEffect(newEffect);
            }
        }
    }

    /**
     * 检查玩家是否穿戴了全套盔甲（四个部位）
     *
     * <p>使用原版Inventory索引方式：</p>
     * <ul>
     *   <li>头盔槽位: getArmor(3)</li>
     *   <li>胸甲槽位: getArmor(2)</li>
     *   <li>护腿槽位: getArmor(1)</li>
     *   <li>靴子槽位: getArmor(0)</li>
     * </ul>
     *
     * @param player 要检查的玩家
     * @return 是否四个盔甲槽位都有物品
     */
    public boolean hasFullSuitOfArmorOn(Player player) {
        // 获取各个部位的盔甲
        ItemStack boots = player.getInventory().getArmor(0);       // 靴子槽位
        ItemStack leggings = player.getInventory().getArmor(1);    // 护腿槽位
        ItemStack chestplate = player.getInventory().getArmor(2);  // 胸甲槽位
        ItemStack helmet = player.getInventory().getArmor(3);      // 头盔槽位

        // 检查所有槽位是否非空
        return !helmet.isEmpty() && !chestplate.isEmpty()
                && !leggings.isEmpty() && !boots.isEmpty();
    }

    /**
     * 检查玩家是否穿戴了特定材质的全套盔甲
     *
     * @param material 要检查的盔甲材质
     * @param player   目标玩家
     * @return 是否所有盔甲部位都是指定材质
     */
    private boolean hasCorrectArmorOn(ArmorMaterial material, Player player) {
        // 获取各个部位的盔甲物品
        ItemStack[] armorStacks = {
                player.getInventory().getArmor(3), // 头盔
                player.getInventory().getArmor(2), // 胸甲
                player.getInventory().getArmor(1), // 护腿
                player.getInventory().getArmor(0)  // 靴子
        };

        // 检查所有部位是否都是盔甲物品
        for (ItemStack stack : armorStacks) {
            if (!(stack.getItem() instanceof ArmorItem)) {
                return false;
            }
        }

        // 获取各个部位的盔甲物品实例
        ArmorItem helmet = (ArmorItem) armorStacks[0].getItem();
        ArmorItem chestplate = (ArmorItem) armorStacks[1].getItem();
        ArmorItem leggings = (ArmorItem) armorStacks[2].getItem();
        ArmorItem boots = (ArmorItem) armorStacks[3].getItem();

        // 检查所有部位材质是否匹配
        return helmet.getMaterial() == material
                && chestplate.getMaterial() == material
                && leggings.getMaterial() == material
                && boots.getMaterial() == material;
    }

    // ============================== 物品提示 ============================== //

    /**
     * 添加物品的悬停提示文本
     *
     * <p>增强的提示信息包括：</p>
     * <ul>
     *   <li>套装效果描述</li>
     *   <li>效果名称和等级（罗马数字）</li>
     *   <li>效果持续时间说明</li>
     *   <li>套装激活条件</li>
     * </ul>
     */
    @Override
    public void appendHoverText(ItemStack stack, @Nullable Level world,
                                List<Component> tooltip, TooltipFlag flag) {
        // 获取当前盔甲的材质
        ArmorMaterial material = this.getMaterial();

        // 添加套装效果描述
        tooltip.add(Component.translatable(getTooltipKeyForMaterial(material)));

        // 添加详细效果列表
        Set<MobEffectInstance> effects = getEffectsForMaterial(material);
        if (!effects.isEmpty()) {
            tooltip.add(Component.translatable("tooltip.creativecraft.effects_header"));

            for (MobEffectInstance effect : effects) {
                // 显示效果名称和等级
                String effectName = effect.getEffect().getDisplayName().getString();
                int amplifier = effect.getAmplifier();
                String romanLevel = toRomanNumeral(amplifier + 1);

                tooltip.add(Component.literal(" - ")
                        .append(Component.translatable("tooltip.creativecraft.effect_entry",
                                effectName, romanLevel)));
            }

            // 添加套装激活提示
            tooltip.add(Component.empty());
            tooltip.add(Component.translatable("tooltip.creativecraft.armor_set_requirement"));
        }

        // 父类的默认提示
        super.appendHoverText(stack, world, tooltip, flag);
    }

    /**
     * 将数字转换为罗马数字（I-X）
     *
     * @param number 要转换的数字（1-10）
     * @return 罗马数字字符串
     */
    private String toRomanNumeral(int number) {
        if (number < 1 || number > 10) {
            return String.valueOf(number);
        }
        return new String[]{"I", "II", "III", "IV", "V",
                "VI", "VII", "VIII", "IX", "X"}[number - 1];
    }
}